import re
import os
import requests
import json
import threading
from concurrent.futures import ThreadPoolExecutor

# 获取cpu核心数
cpu_count = os.cpu_count()


def get_all_text_and_img_src(page, host_id):
    """
    获取所有0-page页中所有的动态内容和图片链接
    :param page: 想要获取的动态页数, 一页为12条
    :param host_id: 想要获取动态的up主uid
    :return: None
    """

    # 动态id
    dynamic_id = '0'
    # 请求头
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, '
                      'like Gecko)Chrome/100.0.4896.75 Safari/537.36 Edg/100.0.1185.39 '
    }

    # 遍历页
    for b in range(page):
        # 请求api
        url = 'https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/space_history?visitor_uid=1&host_uid={}' \
              '&offset_dynamic_id={}&need_top=1&platform=web'

        url = url.format(host_id, dynamic_id)
        # 响应的json文件
        resp = requests.get(url, headers=headers)

        # 该页所有动态内容
        all_text = []
        # 动态下图片的链接
        all_img_src = []

        # 遍历该页所有动态块, 下面将动态块统一称为card
        for i in range(len(resp.json()['data']['cards'])):
            # card信息
            card_info = resp.json()['data']['cards'][i]['card']
            dynamic_id = resp.json()['data']['cards'][i]['desc']['dynamic_id_str']
            # 将card内容转为json
            card_info = json.loads(card_info)

            # 判断有没有item键和description键
            item = card_info.get('item')
            if item is None:
                continue
            if item.get('description') is None:
                continue
            # 判断动态有没有图片
            pictures = item.get('pictures')
            if pictures is None or len(pictures) == 0:
                continue
            # 动态文字内容
            text = card_info['item']['description']
            # 图片链接
            img_src = pictures[0]['img_src']
            # 加入
            all_text.append(text)
            all_img_src.append(img_src)

        # 保存图片
        save_picture(all_text, all_img_src)

        # for i in range(len(all_text)):
        #     print(all_text[i])
        #     print(all_img_src[i])
        # print('=========================================')


def save_picture(all_text, all_img_src):
    """
    保存图片
    :param all_text: 该页所有动态内容
    :param all_img_src: 该页所有图片链接
    :return: None
    """

    # 使用线程池下载图片
    with ThreadPoolExecutor(max_workers=(cpu_count, cpu_count*2)[cpu_count >= 8]) as thread_pool_executor:
        for i in range(len(all_text)):
            text = all_text[i]
            if re.search('22考研', text, re.M):
                # 动态内容中含有22考研, 下同理
                img_src = all_img_src[i]
                thread_pool_executor.submit(save, text, img_src, '22')
            elif re.search('23考研', text, re.M):
                img_src = all_img_src[i]
                thread_pool_executor.submit(save, text, img_src, '23')
            else:
                continue


def save(text, img_src, dir):
    """
    保存图片, 并以年份和题目号命名
    :param text: 动态内容
    :param img_src: 图片链接
    :param dir: 存储文件夹名
    :return: None
    """

    # 获取文件名
    begin = text.find('【') + 1
    end = text.find('】')
    file_name = text[begin: end]

    # 存储文件夹地址, 如果没有则创建
    dir_path = f'D:\\考研\\{dir}'
    if not os.path.exists(dir_path):
        os.mkdir(dir_path)

    # 获取图片信息
    img = requests.get(img_src)
    # 写文件
    with open(f'D:\\考研\\{dir}\\{file_name}.jpg', mode='wb') as f:
        f.write(img.content)
        print(file_name + '下载完成' + threading.currentThread().getName())
        f.close()


if __name__ == '__main__':
    # up的uid
    host_id = '84140046'
    # 页数
    page = 45
    get_all_text_and_img_src(page, host_id)
